from enum import Enum
from typing import Optional, Union, Tuple


class ActionType(Enum):
    active = 0
    passive = 1

class Action:
    def __init__(self, entity:Optional[Union[str, Tuple[str, str]]] = None,
                 act_name:Optional[str] = None,
                 action_type: Optional[ActionType | str] = None) -> None:
        self.entity = entity
        self.act_name = act_name
        match action_type:
            case "active" if isinstance(action_type, str):
                self.action_type = ActionType.active
            case "passive" if isinstance(action_type, str):
                self.action_type = ActionType.passive
            case None:
                self.action_type = None
            case _ if isinstance(action_type, ActionType):
                self.action_type = action_type
            case _:
                raise TypeError("action_type must be str or action_type")
    
    def __str__(self) -> str:
        if self.action_type == ActionType.active:
            return str(self.entity) + " " + str(self.act_name) + " active"
        else:
            return str(self.entity) + " " + str(self.act_name) + " passive"
    
    def __eq__(self, other:Union[any, str]) -> bool:
        match other:
            case Action():
                return self.entity == other.entity and self.act_name == other.act_name and self.action_type == other.action_type
            case str():
                return str(self) == other
            case _:
                return False
        # if isinstance(other, Action):
        #     return self.entity == other.entity and self.act_name == other.act_name and self.action_type == other.action_type
        # else:
    
    def __lt__(self, other ) -> bool:
        if self.entity is None or other.entity is None:
            if self.entity is not None or other.entity is not None:
                raise ValueError("entity cannot be None")
            return self.act_name < other.act_name
        if isinstance(self.entity, str) and isinstance(other.entity, str):
            return self.entity < other.entity
        if isinstance(self.entity, str) and isinstance(other.entity, tuple):
            return self.entity < other.entity[0] 
        if isinstance(self.entity, tuple) and isinstance(other.entity, str):
            return self.entity[0] < other.entity
        return True
        # raise TypeError("entity must be str or tuple")

    def action_entity_type(self):
        if self.entity is None:
            return None
        if isinstance(self.entity, str):
            if self.entity.startswith("n"):
                return "node"
            if self.entity.startswith("s"):
                return "service"
            if self.entity.startswith("a"):
                return "application"
        if isinstance(self.entity, tuple):
            if self.entity[0].startswith("n"):
                return "physical edge"
            if self.entity[0].startswith("s"):
                return "service edge"
        raise TypeError("entity must be str or tuple")


if __name__ == "__main__":
    print(Action())
    print(Action("n1","fail", ActionType.active))
    print(Action("n1","fail", "active") == Action("n1","fail", ActionType.active))
    print(Action("n1","fail", "active") == "n1 fail active")
